package com.nuanshui.framework.task;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

public class TaskManager<T> {
    private static final ExecutorService exec = Executors.newFixedThreadPool(300);//生成固定的线程池
    private HashMap<String,Future<T>> hashMap = new HashMap<String,Future<T>>();  
    private List<String> keys = new ArrayList<String>();
    public void addTask(Object key,Callable<T> callable){  	
       hashMap.put(String.valueOf(key),exec.submit(callable));	
    } 
    public void addTasks(Integer step,Integer total,final TaskHandler<T> taskHandler) {
    	int start =0;
    	int end = 0;
    	final  RequestAttributes requestAttributes =  RequestContextHolder.getRequestAttributes();
    	for(;;) {
    		 end = start+step;	
    		 if(end>total) end  = total;
    		 String key  = String.valueOf(start);
    		 keys.add(key);
    		 hashMap.put(key,exec.submit(new  Task<T>(start,end) {
				@Override
				public T handler() {
					RequestContextHolder.setRequestAttributes(requestAttributes);
					return taskHandler.Handler(getStart(), getEnd());
				}
			}));
    		start  = end;
    		if(end == total) break;
    	}
    }
    public boolean isDone() {
    	while(hashMap.size()>0) {
	       	 Set<String> set = hashMap.keySet();
	       	 for(String k : set){
	       		 Future<T> future = hashMap.get(k);
	       		 if(future.isDone()) {
	           		 hashMap.remove(k);
	           		 break;
	           	 } 
	       	 }
        } 
    	return  true;
    }
    public void addSingleTask(final TaskHandler<T> taskHandler) {
    	addTasks(1, 1, taskHandler);
    	
    }
    public List<T>  getResult()  {
    	 ArrayList<T> list = new ArrayList<T>();
         while(hashMap.size()>0) {
        	 Set<String> set = hashMap.keySet();
        	 for(String k : set){
        		 Future<T> future = hashMap.get(k);
        		 if(future.isDone()) {
            		 try {
						list.add(future.get());
					} catch (InterruptedException e) {
						e.printStackTrace();
					} catch (ExecutionException e) {
						e.printStackTrace();
					}
            		 hashMap.remove(k);
            		 break;
            	 } 
        	 }
         }     
         return list;
    }
    
    
    public List<T>  getSeqResult()  {
   	 ArrayList<T> list = new ArrayList<T>();
   	   for(String  key :keys ) {
   		Future<T> future = hashMap.get(key);
			try {
				list.add(future.get());
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
        }   
        return list;
   }
    
    
    
    
    public void shutdown() {
    	exec.shutdown();
    }

}
